//assign6.cpp

//***************************************************
//*												    *
//*	Student:		Jared Szechy	    		    *
//*	Login id:		cps350-N1.07			        *
//*	Assignment:		6								*
//*	Date:			04/26/08						*
//*													*
//*	This program demonstrates Basic Graph 			*
//*	Implementation Using an Adjacency Matrix.		*										*
//*													*
//***************************************************

#include <iostream>
#include <string>
#include <fstream>
#include <list>
using namespace std;
#include "graph.h"

int main()
{
	//declarations
	string inputFile;                   //the name of the input file
	string outputFile = "szechy6.txt";  //the name of the output file  
	Graph<string> graphArray[10];		//the array of graphs
	ifstream ins;                       //the input stream
	ofstream outs;                      //the output stream
	string command;                     //the operation to be performed 
	int graphNum1, graphNum2;			//used to specify which graph	
	string to, from;					//positions
	int weight;							//edge weight
	string item;						//the item being put into, deleted
	list<string> visited;				//path

	cout << "Please enter the name of the input file: ";
	cin >> inputFile;
	ins.open(inputFile.c_str());       //open input file
	outs.open(outputFile.c_str());     //open output file
	outs << "Jared Szechy" << endl;
	outs << "Input File: " << inputFile << endl << endl;

	//loop to process the input file line by line and call the correct
	//member function depending on the command word.
	while(ins >> command)
	{		
		ins >> graphNum1;
		if (command == "insertnode")
		{
			ins >> item;
			outs << "Command line: " << command << " " << graphNum1 << " " << item << endl;
			graphArray[graphNum1].AddNode(item);
		}
		else if (command == "print")
		{
			outs << "Command line: " << command << " " << graphNum1 << endl;
			graphArray[graphNum1].Print(outs);
		}
		else if (command == "insertedge")
		{
			ins >> from;
			ins >> to;
			ins >> weight;
			outs << "Command line: " << command << " " << graphNum1 << " " << from << " " << to << " " << weight << endl;
			graphArray[graphNum1].AddEdge(from, to, weight);
		}
		else if (command == "change")
		{
			ins >> from;
			ins >> to;
			ins >> weight;
			outs << "Command line: " << command << " " << graphNum1 << " " << from << " " << to << " " << weight << endl;
			graphArray[graphNum1].ChangeEdgeWeight(from, to, weight);
		}
		else if (command == "delnode")
		{
			ins >> item;
			outs << "Command line: " << command << " " << graphNum1 << " " << item << endl;
			graphArray[graphNum1].DeleteNode(item);
		}
		else if (command == "deledge")
		{
			ins >> from;
			ins >> to;
			outs << "Command line: " << command << " " << graphNum1 << " " << from << " " << to << endl;
			graphArray[graphNum1].DeleteEdge(from, to);
		}
		else if (command == "depth")
		{
			ins >> from;
			outs << "Command line: " << command << " " << graphNum1 << " " << from << endl;
			visited = graphArray[graphNum1].Depth(from);
			outs << "\tDepth first traversal of graph " << graphNum1 << " starting at " << from << ": " << endl;
			outs << '\t';
			while (!visited.empty())
			{
				outs << visited.front() << " ";
				visited.pop_front();
			}
			outs << endl;
		}
		else if (command == "breadth")
		{
			ins >> from;
			outs << "Command line: " << command << " " << graphNum1 << " " << from << endl;
			visited = graphArray[graphNum1].Breadth(from);
			outs << "\tBreadth first traversal of graph " << graphNum1 << " starting at " << from << ": " << endl;
			outs << '\t';
			while (!visited.empty())
			{
				outs << visited.front() << " ";
				visited.pop_front();
			}
			outs << endl;
		}
		else if (command == "path")
		{
			ins >> from;
			ins >> to;
			outs << "Command line: " << command << " " << graphNum1 << " " << from << " " << to << endl;
			visited = graphArray[graphNum1].findPath(from, to);
			if (visited.back() != to)
				outs << "\tThere is no path from " << from << " to " << to << endl;
			else
			{
				outs << "\tA path from " << from << " to " << to << endl;
				outs << '\t';
				while (!visited.empty())
				{
					outs << visited.front() << " ";
					visited.pop_front();
				}
				outs << endl;
			}
		}
		else if (command == "undirected")
		{
			outs << "Command line: " << command << " " << graphNum1 << endl;
			if(graphArray[graphNum1].isUndirected())
				outs << "\tGraph " << graphNum1 << " is undirected." << endl;
			else
				outs << "\tGraph " << graphNum1 << " is not undirected." << endl;
		}
		else if (command == "within")
		{
			ins >> from;
			ins >> weight;
			outs << "Command line: " << command << " " << graphNum1 << " " << from << " " << weight << endl;
			visited = graphArray[graphNum1].NodesWithinNEdges(from, weight);
			outs << "\tNodes within " << weight << " edges of " << from << ": " << endl;
			outs << '\t';
			while (!visited.empty())
			{
				outs << visited.front() << " ";
				visited.pop_front();
			}
			outs << endl;
		}
		else if (command == "flow")
		{
			ins >> graphNum2;
			outs << "Command line: " << command << " " << graphNum1 << " " << graphNum2 << endl;
			graphArray[graphNum1].findNetworkFlow(graphArray[graphNum2]);
		}
	}

	return 0;
}